#include "HouseDemoScene.h"

//To move back to game scene
#include "SceneManager.h"

//Complete forward declarations
#include "SkyDome.h"

HouseDemoSceneOne::HouseDemoSceneOne()
{
	//Models - init to NULL within the constructor. Memory should be allocated
	//in the OpenScene() function and memroy deleted in CloseScene().  
	skyDome = 0;

	floor = 0;
	roof = 0;

	for (UINT i = 0; i < 4; i++)
		backWall[i] = 0;


	frontWall = 0;
	leftWall = 0;
	rightWall = 0;

	box = 0;
	collumns = 0;
}

HouseDemoSceneOne::~HouseDemoSceneOne()
{}

void HouseDemoSceneOne::OpenScene()
{
	//Seed random number generator to a known number - thus, each time we run the game, the 
	//point/spot lights will be located and coloured exactly the same. 
	srand(10);

	//Set MSAA State
#ifdef HOUSE_DEMO_SCENE_ONE_SCENE_ENABLE_MSAA
	sharedGraphicsInterface->Set4XMSAA(true);
#else
	sharedGraphicsInterface->Set4XMSAA(false);
#endif

	//Init camera position / frustum properties.
	camera->SetPosition(XMFLOAT3(0.0f, 2.0f, 0.0f));
	camera->RebuildViewMatrix();
	OnResize();

	//Load the skydome FIRST
	LoadSkyDome();

	//Load Models (After skydome)
	LoadModels();

	//Init lights
	InitLighting();
	InitDirecLight();
	InitHemisphericalAmbientLight();

	//Initial Scene State is to draw scene as usual.
	sceneState = SCENE_STATE_DRAW_SCENE;
	//Lights initially to be rendered
	shouldRenderLights = true;

	//We want shadow mapping
	sharedGraphicsInterface->SetIsShadowMappingEnabled(true);
}

void HouseDemoSceneOne::CloseScene()
{
	//Delete models
	SafeDelete(skyDome);

	//Delete walls/floor etc
	SafeDelete(floor);
	SafeDelete(roof);

	for (UINT i = 0; i < 4; i++)
		SafeDelete(backWall[i]);
	

	SafeDelete(frontWall);
	SafeDelete(leftWall);
	SafeDelete(rightWall);

	SafeDelete(box);
	SafeDelete(collumns);
}

void HouseDemoSceneOne::LoadModels()
{
	//Load room
	LoadFloor();
	LoadRoof();
	LoadBackWall();
	LoadFrontWall();
	LoadLeftWall();
	LoadRightWall();

	//Load box in the middle
	LoadBox();

	//Load 4 collumsn
	LoadCollumns();
}

void HouseDemoSceneOne::LoadCollumns()
{
	//Fillout collumn model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/bricks_nmap.dds";
	m.TextureMapFilePath = L"Textures/bricks.dds";

	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.3f, 0.3f, 0.3f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 32.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	//No tex scaling
	m.TexScale = XMFLOAT2(5.0f, 5.0f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Create collum vertex data (4 of them)
	collumns = new StaticInstancedModel(sharedGraphicsInterface->GetDevice(), 4);
	collumns->CreateCollum(0.5f, 0.5f, 3.0f, 25, 1, &m, 
		sharedGraphicsInterface->GetDevice());

	//Create 4 instances
	//
	//BL
	collumns->CreateInstance(XMFLOAT3(-5.0f, 1.5f, 5.0f), 
		XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));

	//BR
	collumns->CreateInstance(XMFLOAT3(5.0f, 1.5f, 5.0f), 
		XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));

	//FL
	collumns->CreateInstance(XMFLOAT3(-5.0f, 1.5f, -5.0f), 
		XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));

	//FR
	collumns->CreateInstance(XMFLOAT3(5.0f, 1.5f, -5.0f), 
		XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadBox()
{
	//Fillout box model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/GLDemo/four_NM_height.png";
	m.TextureMapFilePath = L"Textures/GLDemo/four_diffuse.jpg";

	m.Material.Ambient = XMFLOAT4(0.1f, 0.1f, 0.1f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 8.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	//No tex scaling
	m.TexScale = XMFLOAT2(1.0f, 1.0f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the floor model
	box = new StaticModel();
	box->CreateBox(1, 1, 1, &m, sharedGraphicsInterface->GetDevice());

	//Set location
	box->SetWorldMatrix(XMFLOAT3(0.0f, 1.5f, 4.5f), 
		XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadFloor()
{
	//Fillout floor model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/GLDemo/woodfloor005a_NM.jpg";
	m.TextureMapFilePath = L"Textures/GLDemo/woodfloor005a_diffuse.jpg";
	
	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.4f, 0.4f, 0.4f, 64.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	m.TexScale = XMFLOAT2(7.5f, 7.5f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the floor model
	floor = new StaticModel();
	floor->CreateGrid(15, 15, 2, 2, &m, sharedGraphicsInterface->GetDevice());

	//Set location
	floor->SetWorldMatrix(XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadRoof()
{
	//Fillout floor model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/floor_nmap.dds";
	m.TextureMapFilePath = L"Textures/floor.dds";

	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.1f, 0.1f, 0.1f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 4.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	m.TexScale = XMFLOAT2(7.5f, 7.5f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the wall model
	roof = new StaticModel();
	roof->CreateBox(15, 15, 1, &m, sharedGraphicsInterface->GetDevice());

	//Set location
	roof->SetWorldMatrix(XMFLOAT3(0.0f, 5.5f, 0.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+180.0f), 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadBackWall()
{
	//Fillout floor model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/GLDemo/stones_NM_height.png";
	m.TextureMapFilePath = L"Textures/GLDemo/stones_diffuse.jpg";

	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 8.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	m.TexScale = XMFLOAT2(3.0f, 2.5f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the wall model (s)
	backWall[0] = new StaticModel();
	backWall[0]->CreateBox(6, 5, 1, &m, sharedGraphicsInterface->GetDevice());
	//Set location
	backWall[0]->SetWorldMatrix(XMFLOAT3(-4.5f, 2.5f, -8.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+90.0f), 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));

	//Second.
	backWall[1] = new StaticModel();
	backWall[1]->CreateBox(6, 5, 1, &m, sharedGraphicsInterface->GetDevice());
	//Set location
	backWall[1]->SetWorldMatrix(XMFLOAT3(4.5f, 2.5f, -8.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+90.0f), 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));

	//Much smaller model so modify tex scaling. 
	m.TexScale = XMFLOAT2(1.5f, 0.75f);

	//Third.
	backWall[2] = new StaticModel();
	backWall[2]->CreateBox(3, 1.5, 1, &m, sharedGraphicsInterface->GetDevice());
	//Set location
	backWall[2]->SetWorldMatrix(XMFLOAT3(0.0f, 0.75f, -8.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+90.0f), 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));

	//Final
	backWall[3] = new StaticModel();
	backWall[3]->CreateBox(3, 1.5, 1, &m, sharedGraphicsInterface->GetDevice());
	//Set location
	backWall[3]->SetWorldMatrix(XMFLOAT3(0.0f, 4.25f, -8.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+90.0f), 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadFrontWall()
{
	//Fillout floor model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/GLDemo/stones_NM_height.png";
	m.TextureMapFilePath = L"Textures/GLDemo/stones_diffuse.jpg";

	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 8.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	m.TexScale = XMFLOAT2(7.5f, 2.5f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the wall model
	frontWall = new StaticModel();
	frontWall->CreateGrid(15, 5, 2, 2, &m, sharedGraphicsInterface->GetDevice());

	//Set location
	frontWall->SetWorldMatrix(XMFLOAT3(0.0f, 2.5f, 7.5f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f), MathHelper::ToRadians(180.0f), 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadLeftWall()
{
	//Fillout floor model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/GLDemo/stones_NM_height.png";
	m.TextureMapFilePath = L"Textures/GLDemo/stones_diffuse.jpg";

	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 8.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	m.TexScale = XMFLOAT2(7.5f, 2.5f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the wall model (s)
	leftWall = new StaticModel();
	leftWall->CreateBox(17, 5, 1, &m, sharedGraphicsInterface->GetDevice());
	//Set location
	leftWall->SetWorldMatrix(XMFLOAT3(-8.0f, 2.5f, 0.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+90.0f), MathHelper::ToRadians(90.0f), 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadRightWall()
{
	//Fillout floor model material struct. 
	StaticModelBasicMaterial m;
	m.HeightMapFilePath = L"";
	m.NormalMapFilePath = L"Textures/GLDemo/stones_NM_height.png";
	m.TextureMapFilePath = L"Textures/GLDemo/stones_diffuse.jpg";

	m.Material.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	m.Material.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
	m.Material.Specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 8.0f);
	m.Material.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	m.TexScale = XMFLOAT2(7.5f, 2.5f);

	m.IsOpaque = true;

	m.UseDisplacementMap = false;
	m.UseNormalMap = true;
	m.UseSeperateHeightMap = false;
	m.UseTextureMap = true;

	//Alloc memory and create the wall model (s)
	rightWall = new StaticModel();
	rightWall->CreateBox(15, 5, 1, &m, sharedGraphicsInterface->GetDevice());
	//Set location
	rightWall->SetWorldMatrix(XMFLOAT3(7.5f, 2.5f, 0.0f), 
		XMFLOAT3(MathHelper::ToRadians(90.0f+90.0f), MathHelper::ToRadians(90.0f), 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::LoadSkyDome()
{
	skyDome = new SkyDome(sharedGraphicsInterface->GetDevice(),
		//L"Terrain/QuantumTheory/QuantumHighlands/Textures/SkyDome/cubeMap.dds", 
		L"Textures/snowcube1024.dds",
		camera);
	sharedGraphicsInterface->SetCurrentSkyDome(skyDome);
}

void HouseDemoSceneOne::InitLighting()
{
	//Set scene lighting. Randomly place lights in a grid: 40x10x60
	//Done using new to avoid stack overflow issues when we have > 3000 lights
	//or so.
	TileBasedLight* lightArr = new TileBasedLight[HOUSE_DEMO_SCENE_ONE_NUM_LIGHTS];
	//Loop through lights and set properties.
	for (UINT i = 0; i < HOUSE_DEMO_SCENE_ONE_NUM_LIGHTS; i++)
	{
		//No colour output. 
		XMFLOAT4 null = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
		//Random diffuse and spec colour.
		XMFLOAT4 diffDiffCol = XMFLOAT4(MathHelper::RandF(), MathHelper::RandF(), 
			MathHelper::RandF(), 1.0f);
		XMFLOAT4 diffSpecCol = diffDiffCol;

		//Ambient term
		XMFLOAT4 amb = XMFLOAT4(diffSpecCol.x/5.0f, diffSpecCol.y/5.0f, 
			diffSpecCol.z/5.0f, 1.0f);
		//Random location.
		XMFLOAT3 randLoc = XMFLOAT3(MathHelper::RandF(-7.5f, 7.5f),
			MathHelper::RandF(0.1f, 4.5f), MathHelper::RandF(-7.5f, 7.5f));

		//Randon range.
		float randRange = MathHelper::RandF(1.0f, 5.0f);
		//Create point lights. 
		lightArr[i].InitPointLight(amb, diffDiffCol, diffSpecCol, 
			randLoc, randRange);
	}

	//Set scene lighting - creating our required buffers - we want the option
	//to visualise our lights, so set the required bool to true.
	sharedGraphicsInterface->SetSceneLights(&lightArr[0], HOUSE_DEMO_SCENE_ONE_NUM_LIGHTS, true);

	//Delete dynamically allocated light array.
	delete []lightArr;
}

void HouseDemoSceneOne::InitDirecLight()
{
	//Shadow map boundary. 
	ShadowMapBoundingSphere bs;
	bs.Center = XMFLOAT3(0.0f, 0.0f, 0.0f);
	bs.SetRadius(15, 15);

	//Set Directional light. 
	dLight.Ambient = XMFLOAT4(0.06f, 0.06f, 0.06f, 1.0f);
	dLight.Diffuse = XMFLOAT4(0.6f, 0.6f, 0.6f, 1.0f);
	dLight.Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 128.0f);
	dLight.Direction = XMFLOAT3(0.75f, -0.32f, +1.0f);

	//Set single directional light 
	sharedGraphicsInterface->SetDirectionalLights(&dLight, 1, &bs);
}

void HouseDemoSceneOne::InitHemisphericalAmbientLight()
{
	//sharedGraphicsInterface->SetHemisphericAmbientColours(XMFLOAT3(0.0f, 0.0f, 0.0f), 
	//	XMFLOAT3(0.298f, 0.4078f, 0.4745f));
	//sharedGraphicsInterface->SetHemisphericAmbientColours(XMFLOAT3(0.0f, 0.0f, 0.0f), 
	//	XMFLOAT3(0.600f, 0.8508f, 0.917f));
	sharedGraphicsInterface->SetHemisphericAmbientColours(XMFLOAT3(0.0f, 0.0f, 0.0f), 
		XMFLOAT3(1.0f, 1.0f, 1.0f));
	//sharedGraphicsInterface->SetHemisphericAmbientColours(XMFLOAT3(1.0f, 0.5f, 0.15f), 
	//	XMFLOAT3(1.0f, 1.0f, 1.0f));
}

void HouseDemoSceneOne::OnMouseDown(WPARAM btnState, int x, int y, UINT originalMessage)
{
	AbstractScene::OnMouseDown(btnState, x, y, originalMessage);
}

void HouseDemoSceneOne::OnMouseUp(WPARAM btnState, int x, int y, UINT originalMessage)
{}

void HouseDemoSceneOne::OnMouseMove(WPARAM btnState, int x, int y)
{
	//Rather than use default method which will (eventually) lock the cameras
	//pitch to a certain range, use my own systems. 
	if( (btnState & MK_LBUTTON) != 0 )
	{
		// Make each pixel correspond to a quarter of a degree.
		float dx = 0.25f*static_cast<float>(x - lastMPos.x);
		float dy = 0.25f*static_cast<float>(y - lastMPos.y);

		camera->AddPitch(dy);
		camera->AddYaw(dx);
	} 

	lastMPos.x = x;
	lastMPos.y = y;
}

void HouseDemoSceneOne::OnResize()
{
	AbstractScene::OnResize();
}

void HouseDemoSceneOne::UpdateWithDelta(float delta)
{
	//Manually move camer (Ignores the camera movement
	//multiplier)
	if( GetAsyncKeyState('W') & 0x8000 )
		camera->Walk(3.0f*delta*1.0f);

	if( GetAsyncKeyState('S') & 0x8000 )
		camera->Walk(-3.0f*delta*1.0f);

	if( GetAsyncKeyState('A') & 0x8000 )
		camera->Strafe(-3.0f*delta*1.0f);

	if( GetAsyncKeyState('D') & 0x8000 )
		camera->Strafe(3.0f*delta*1.0f);

	//Rebuild camera view matrix
	camera->RebuildViewMatrix();

	//Rotate box. 
	float boxRotY = box->GetWorldRotation().y;
	boxRotY+=MathHelper::ToRadians(45.0f*delta);
	box->SetWorldRotation(XMFLOAT3(0.0f, boxRotY, 0.0f));

	//Update single directional light 
	//
	//First, calculate the shadow map boundary. 
	ShadowMapBoundingSphere bs;
	bs.Center = XMFLOAT3(0.0f, 0.0f, 0.0f);
	bs.SetRadius(15, 15);
	sharedGraphicsInterface->SetDirectionalLights(&dLight, 1, &bs);

	//Decide what to render?
	if( GetAsyncKeyState('1') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_SCENE; 
	if( GetAsyncKeyState('2') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_Z_PRE_PASS_DEPTH_BUFFER; 
	if ( GetAsyncKeyState('3') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_CS_MAX_Z_DEPTH_BUFFER;
	if ( GetAsyncKeyState('4') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_CS_LLSEB_GREYSCALE;
	if ( GetAsyncKeyState('5') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_CS_LLSEB_COLOUR;
	if ( GetAsyncKeyState('6') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_CS_LLSEBT_GREYSCALE;
	if ( GetAsyncKeyState('7') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_CS_LLSEBT_COLOUR;
	if ( GetAsyncKeyState('8') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_SSAO_VIEW_NORMALS;
	if ( GetAsyncKeyState('9') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_SSAO_VIEW_DEPTHS;
	if ( GetAsyncKeyState('0') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_SSAO_MAP;
	if ( GetAsyncKeyState('L') & 0x8000 )
		sceneState = SCENE_STATE_DRAW_SHADOW_DEPTH;

	//Render the lights?
	if ( GetAsyncKeyState('G') & 0x8000 )
		shouldRenderLights = true;
	if ( GetAsyncKeyState('F') & 0x8000 )
		shouldRenderLights = false;

	//Should go back to game scene?
	if ( GetAsyncKeyState('E') & 0x8000 )
	{
		//Debug message
		OutputDebugStringW(L"House Demo Scene - Transitioning back to the Game Scene!\n");
		
		//Tranaition back to game scene - we will unload this scenes data but, since the 
		//game scene has already had its data loaded and stored in GPU memory, we do not
		//need to reload the game scene. 
		SceneManager::GetInstance()->TransitionToSceneWithKey("Roo's World", true, false);
	}
}

void HouseDemoSceneOne::RenderScene()
{
	//Start rendering - Clear backbuffer and depth stencil view - Scene manually
	//updates shadow map (NOT the engine as we do in the game)
	float clearColGrey[4] = {0.6f, 0.6f, 0.6f, 1.0f};
	sharedGraphicsInterface->StartFrame(clearColGrey, camera, false);

	//Add models to the batch.
	//
	//Walls
	sharedGraphicsInterface->AddModelToBatch(floor);
	sharedGraphicsInterface->AddModelToBatch(roof);
	sharedGraphicsInterface->AddModelToBatch(frontWall);
	sharedGraphicsInterface->AddModelToBatch(leftWall);
	sharedGraphicsInterface->AddModelToBatch(rightWall);

	//Back walls (4 of them)
	for (UINT i = 0; i < 4; i++)
		sharedGraphicsInterface->AddModelToBatch(backWall[i]);

	//Finally, the normal mapped geometry
	sharedGraphicsInterface->AddModelToBatch(collumns);
	sharedGraphicsInterface->AddModelToBatch(box);

	//Render the 3D scene.
	sharedGraphicsInterface->Render(shouldRenderLights);

	//Begin 2D rendering (Text/HUD)
	sharedGraphicsInterface->Begin2DRendering();
	//End of text rendering
	sharedGraphicsInterface->End2DRendering();

	//Debug Rendering
	//
	//Draw depth buffer (filled from Z Pre Pass).
	if (sceneState == SCENE_STATE_DRAW_Z_PRE_PASS_DEPTH_BUFFER)
		sharedGraphicsInterface->DrawZPrePassFilledDepthBuffer();
	//Draw max tile depth texture.
	else if (sceneState == SCENE_STATE_DRAW_CS_MAX_Z_DEPTH_BUFFER)
		sharedGraphicsInterface->DrawTileMaxZBuffer(); 
	else if (sceneState == SCENE_STATE_DRAW_CS_LLSEB_GREYSCALE)
		sharedGraphicsInterface->DrawLightListStartEndBufferGreyscale();
	else if (sceneState == SCENE_STATE_DRAW_CS_LLSEB_COLOUR)
		sharedGraphicsInterface->DrawLightListStartEndBufferColour();
	else if (sceneState == SCENE_STATE_DRAW_CS_LLSEBT_GREYSCALE)
		sharedGraphicsInterface->DrawLightListStartEndBufferTransparantGreyscale();
	else if (sceneState == SCENE_STATE_DRAW_CS_LLSEBT_COLOUR)
		sharedGraphicsInterface->DrawLightListStartEndBufferTransparantColour();
	else if (sceneState == SCENE_STATE_DRAW_SSAO_VIEW_NORMALS)
		sharedGraphicsInterface->DrawSSAOViewNormals();
	else if (sceneState == SCENE_STATE_DRAW_SSAO_VIEW_DEPTHS)
		sharedGraphicsInterface->DrawSSAOViewDepths();
	else if (sceneState == SCENE_STATE_DRAW_SSAO_MAP)
		sharedGraphicsInterface->DrawSSAOMap();
	else if (sceneState == SCENE_STATE_DRAW_SHADOW_DEPTH)
		sharedGraphicsInterface->DrawShadowMapDepth();

	//Present the backbuffer (if in full screen, present with vsync on)
	bool fsState = sharedGraphicsInterface->IsInFullScreenMode();
	sharedGraphicsInterface->EndFrame(fsState);
}